/*
 * Created by Wildish on 2016-10-31
 *
 * Contact me with keithknight@qq.com
 *
 * Copyright (c) 2016 Wildish
 */
package com.wildish.hybridframework.jsbinding.webview;

import android.graphics.Bitmap;
import android.net.Uri;
import android.util.Base64;
import android.webkit.WebResourceResponse;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import com.liulishuo.filedownloader.BaseDownloadTask;
import com.liulishuo.filedownloader.FileDownloadListener;
import com.liulishuo.filedownloader.FileDownloader;
import com.liulishuo.filedownloader.model.FileDownloadStatus;
import com.wildish.hybridframework.core.HybridGlobal;
import com.wildish.hybridframework.jsbinding.proxy.HybridProxyManager;
import com.wildish.hybridframework.utils.NetworkUtil;

import org.apache.commons.lang3.StringUtils;
import org.json.JSONObject;

import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class CustomWebClient extends WebViewClient {
    private ArrayList<BaseDownloadTask> taskList = new ArrayList<>();

    @Override
    public void onPageStarted(WebView view, String url, Bitmap favicon) {
        stopAllDownload();
        super.onPageStarted(view, url, favicon);
    }

    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        try{
            if (url != null && url.startsWith(HybridGlobal.getCustomScheme() + "://")) {
                Uri uri = Uri.parse(url);
                String host = uri.getHost();
                String query = uri.getQuery();
                JSONObject params = new JSONObject(new String(Base64.decode(query.getBytes(), Base64.DEFAULT)));
                String action = params.optString(HybridProxyManager.METHOD_KEY, null);
                if(StringUtils.isNotBlank(action)) {
                    HybridProxyManager.getInstance().execute(view.getContext(), host, action, params);
                } else {
                    HybridGlobal.logger.log("未定义method_key，无法完成proxy调用");
                }
            } else {
                view.loadUrl(url);
            }
        } catch(Exception e) {
            HybridGlobal.logger.log(e);
        }
        return true;

        // 使用CUSTOM_SCHEME
//        if (url != null && url.startsWith(HybridGlobal.getCustomScheme() + "://")) {
//            //view.getContext().startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
//            view.getContext().sendBroadcast(new Intent(HybridGlobal.ACTION_HYBRID_SCHEME_ACTION, Uri.parse(url)));
//            return true;
//        } else {
//            view.loadUrl(url);
//            return true;
//        }
    }

    @Override
    public void onLoadResource(WebView view, String url) {
        super.onLoadResource(view, url);

        // download file
        if (url.contains("http://downloadfile")) {
            Matcher m = Pattern.compile("(\\?|&+)(.+?)=([^&]*)").matcher(url);
            String fileUrl = "";
            int width = 0;
            String type = "";
            while (m.find()) {
                String key = m.group(2);
                if ("src".equals(key)) {
                    if (StringUtils.isNotBlank(m.group(3))) {
                        fileUrl = new String(Base64.decode(m.group(3), Base64.DEFAULT));
                    }
                } else if("width".equals(key)) {
                    if (StringUtils.isNotBlank(m.group(3))) {
                        width = Integer.valueOf(m.group(3));
                    }
                } else if("type".equals(key)) {
                    if (StringUtils.isNotBlank(m.group(3))) {
                        type = m.group(3);
                    }
                }
            }

            fileUrl = HybridGlobal.getImageFilePath(fileUrl, width);
            if (StringUtils.isNotBlank(fileUrl)) {
                String fileName = fileUrl.substring(fileUrl.lastIndexOf("/") + 1);
                String localFilePath = HybridGlobal.getTempFolder().getAbsolutePath() + File.separator + fileName;
                String remoteFileUrl = fileUrl;

                File localFile = new File(localFilePath);
                if(localFile.exists()) {
                    String suffix = fileUrl.substring(fileUrl.lastIndexOf("."));
                    if(StringUtils.isNotBlank(HybridGlobal.IMAGESIZE_ARRAY)) {
                        for(String s : HybridGlobal.IMAGESIZE_ARRAY.split(",")) {
                            if(StringUtils.isNotBlank(s)) {
                                if(fileUrl.indexOf("_" + s + suffix) > 0) {
                                    fileUrl = fileUrl.replace("_" + s + suffix, suffix);
                                    break;
                                }
                            }
                        }
                    }

                    //加载本地文件
                    HybridGlobal.getCurrentWebView().loadUrl("javascript:$win.getDefaultProxy().cb_downloader({" +
                        "\"url\": \"" + fileUrl + "\", " +
                        "\"path\": \"" + localFile.getAbsolutePath() + "\"," +
                        "\"total\": " + 0 + "," +
                        "\"current\": " + 0 + "," +
                        "\"textStatus\": \"complete\"" +
                    "})");
                } else {
                    // 下载文件
                    if (NetworkUtil.getNetWorkType(view.getContext()) != NetworkUtil.NONETWORK) {
                        downloadFile(remoteFileUrl, localFilePath, type);
                    } else {
                        HybridGlobal.getCurrentWebView().loadUrl("javascript:$win.getDefaultProxy().cb_downloader({" +
                            "\"url\": \"" + fileUrl + "\", " +
                            "\"path\": \"\"," +
                            "\"total\": 0," +
                            "\"current\": 0," +
                            "\"textStatus\": \"error\"" +
                        "})");
                    }
                }
            }
        } else {
            super.onLoadResource(view, url);
        }
    }

    public void stopAllDownload() {
        for(BaseDownloadTask task : taskList) {
            try{
                if(!FileDownloadStatus.isOver(task.getStatus())) {
                    HybridGlobal.logger.log("关闭下载:" + task.getUrl());
                    task.pause();
                }
            } catch (Exception e){
            }
        }
    }

    @Override
    public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
        if (url.contains("localfile")) {
            try {
                return getLocalResource(url);
            } catch (Exception e) {
                return null;
            }
        } else {
            return super.shouldInterceptRequest(view, url);
        }
    }

    private WebResourceResponse getLocalResource(String url) throws Exception {
        Matcher m = Pattern.compile("(\\?|&+)(.+?)=([^&]*)").matcher(url);
        String filePath = "";
        while (m.find()) {
            String key = m.group(2);
            if ("src".equals(key)) {
                if (StringUtils.isNotBlank(m.group(3))) {
                    filePath = new String(Base64.decode(m.group(3), Base64.DEFAULT));
                    if(filePath.contains("_timestamp_")) {
                        filePath = filePath.substring(0, filePath.indexOf("_timestamp_"));
                    }
                    break;
                }
            }
        }
        File file = new File(filePath);
        WebResourceResponse res = null;
        if (file.exists()) {
            FileInputStream fis = new FileInputStream(file);
            String s;
            if (StringUtils.isNotBlank(s = matchPic(filePath).toLowerCase())) {
                s = s.equals("jpg") ? "jpeg" : s;
                res = new WebResourceResponse("image/" + s, "UTF-8", fis);
            }
        }

        return res;
    }

    // load Resource from zip file
//    private WebResourceResponse getResource(String url) {
//        WebResourceResponse res = null;
//
//        long begin = System.currentTimeMillis();
//
//        // load local resource file
//        if (matchReq(url)) {
//            HybirdGlobal.logger.log("load resource for " + url + " begin.", Logger.Debug);
//            String filePath = url.replace("http://127.0.0.1:" + HybirdGlobal.port + "/", "");
//            if (filePath.contains("?")) {
//                filePath = filePath.substring(0, filePath.indexOf("?"));
//            }
//            try {
//                // extract file to temp folder
//                long begin1 = System.currentTimeMillis();
//                ZipFile webZipFile = new ZipFile(HybirdGlobal.webZipFile);
//                HybirdGlobal.logger.log("init zipEntity cost " + (System.currentTimeMillis() - begin1) + "ms", Logger.Debug);
//
//                long begin2 = System.currentTimeMillis();
//                File tempFile = new File(HybirdGlobal.getTempFolder(), filePath);
//                webZipFile.extractFile(filePath, HybirdGlobal.getTempFolder().getAbsolutePath());
//                HybirdGlobal.logger.log("extract file cost " + (System.currentTimeMillis() - begin2) + "ms", Logger.Debug);
//
//                long begin3 = System.currentTimeMillis();
//                FileInputStream fis = new FileInputStream(tempFile);
//                String s;
//                if (StringUtils.isNotBlank(s = matchPic(filePath).toLowerCase())) {
//                    s = s.equals("jpg") ? "jpeg" : s;
//                    res = new WebResourceResponse("image/" + s, "UTF-8", fis);
//                } else if (filePath.endsWith(".html")) {
//                    res = new WebResourceResponse("text/html", "UTF-8", fis);
//                } else if (filePath.endsWith(".js")) {
//                    res = new WebResourceResponse("application/x-javascript", "UTF-8", fis);
//                } else if (filePath.endsWith(".css")
// ) {
//                    res = new WebResourceResponse("text/css", "UTF-8", fis);
//                }
//                HybirdGlobal.logger.log("read file cost " + (System.currentTimeMillis() - begin3) + "ms", Logger.Debug);
//            } catch (Exception e) {
//                HybirdGlobal.logger.log(e, Logger.Exception);
//            }
//            HybirdGlobal.logger.log("load resource for " + url + " end cost " + (System.currentTimeMillis() - begin) + "ms", Logger.Debug);
//        }
//        return res;
//    }
//
//    private boolean matchReq(String url) {
//        return url.contains("http://127.0.0.1:" + HybirdGlobal.port + "/") &&
//                !url.contains(".do?");
//    }

    private String matchPic(String str) {
        Matcher m = Pattern.compile("(?i).+?\\.(jpg|gif|bmp|png|jpeg)", Pattern.CASE_INSENSITIVE).matcher(str);
        String result = "";
        if (m.matches()) {
            result = m.group(1);
        }
        return result;
    }

    /**
     * 下载功能实现begin
     */
    private void downloadFile(String url, String destPath, String type) {
        BaseDownloadTask task = FileDownloader.getImpl().create(url)
                .setPath(destPath)
                .setCallbackProgressTimes(100)
                .setListener(downloadListener)
                .setTag(type);
        task.start();
        taskList.add(task);
    }

    private FileDownloadListener downloadListener = new FileDownloadListener() {
        @Override
        protected void pending(BaseDownloadTask task, int soFarBytes, int totalBytes) {
        }

        @Override
        protected void progress(BaseDownloadTask task, int soFarBytes, int totalBytes) {
            fileDownloadCallback(task, "progress");
        }

        @Override
        protected void blockComplete(BaseDownloadTask task) {
        }

        @Override
        protected void completed(BaseDownloadTask task) {
            fileDownloadCallback(task, "complete");
        }

        @Override
        protected void paused(BaseDownloadTask task, int soFarBytes, int totalBytes) {
            fileDownloadCallback(task, "paused");
        }

        @Override
        protected void error(BaseDownloadTask task, Throwable e) {
            fileDownloadCallback(task, "error");
        }

        @Override
        protected void warn(BaseDownloadTask task) {
        }
    };

    private void fileDownloadCallback(BaseDownloadTask task, String textStatus) {
        String url = task.getUrl();

        if(!url.contains(".")) {
            return;
        }

        String type = (String) task.getTag();
        if(!"file".equals(type)) {
            String suffix = url.substring(url.lastIndexOf("."));
            if(StringUtils.isNotBlank(HybridGlobal.IMAGESIZE_ARRAY)) {
                for(String s : HybridGlobal.IMAGESIZE_ARRAY.split(",")) {
                    if(StringUtils.isNotBlank(s)) {
                        if(url.indexOf("_" + s + suffix) > 0) {
                            url = url.replace("_" + s + suffix, suffix);
                            break;
                        }
                    }
                }
            }
        }

        HybridGlobal.getCurrentWebView().loadUrl("javascript:$win.getDefaultProxy().cb_downloader({" +
                "\"url\": \"" + url + "\", " +
                "\"path\": \"" + task.getPath() + "\"," +
                "\"total\": " + task.getSmallFileTotalBytes() + "," +
                "\"current\": " + task.getSmallFileSoFarBytes() + "," +
                "\"textStatus\": \"" + textStatus + "\"" +
        "})");
    }
    /**
     * 下载功能实现end
     */
}
